package br.com.lvc.bicho.memorygame;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

import android.content.DialogInterface;
import android.os.Bundle;
import android.view.View;
import android.view.animation.Animation;
import android.widget.Toast;
import br.com.lvc.bicho.AnimalButton;
import br.com.lvc.bicho.AnimalGameActivity;
import br.com.lvc.bicho.AnimationController;
import br.com.lvc.bicho.DialogUtils;
import br.com.lvc.bicho.R;
import br.com.lvc.bicho.standartgame.TextSpeech;

public class MemoryGameActivity extends AnimalGameActivity {

	private boolean canTouch = false;
	private int clickCount = 0;
	private List<Integer> sequenceIndexExpected;
	private ExecutorSequencia executorSequencia;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		executorSequencia = new ExecutorSequencia();
		exibirMensagemIniciarSequencia();
	}

	private void exibirMensagemIniciarSequencia() {
		DialogInterface.OnClickListener positiveEvent = new DialogInterface.OnClickListener() {

			public void onClick(DialogInterface dialog, int which) {
				dialog.cancel();
				executarSequencia();		
			}
		};
		DialogUtils.showDialog(R.drawable.cat, R.string.welcome, R.string.deseja_iniciar_jogo_memoria, this, positiveEvent);
	}

	@Override
	protected boolean startAnimationOnInit() {
		return false;
	}

	@Override
	public void configureLayout() {
		findViewById(R.id.linear_botoon_layout).setVisibility(View.GONE);   
	}

	@Override
	protected AnimalButton createAnimalButton(int drawable, TextSpeech text,int sound) {
		return new AnimalButton(this, this, drawable, sound);
	}

	public void pressed(AnimalButton animalButton) {
		if(isPossibleTouch()) {
			clickAction(animalButton);
		} else { // Sequencia em andamento
			clickCount = 0;
			exibirToastMessage(R.string.aguarde_sua_vez);
		}
	}

	private void clickAction(final AnimalButton animalButton) {
		playSound(animalButton);
		Animation animation = AnimationController.createAnimationIncreaseSizeFaster(MemoryGameActivity.this);

		animation.setAnimationListener(new EndAnimationListener() {

			public void onAnimationEnd(Animation animation) {
				tratarSeAcertouOuErrouSequencia(animalButton);
			}
		});

		animalButton.startAnimation(animation);		
	}

	private void tratarSeAcertouOuErrouSequencia(AnimalButton animalButton) {
		int index = sequenceIndexExpected.get(clickCount);
		AnimalButton animalExpected =  animais.get(index);
		if(animalExpected.equals(animalButton)) {
			tratarAcerto();
		} else {
			exibirMensagemErrouSequencia(sequenceIndexExpected.size());
		}
	}

	private void exibirMensagemErrouSequencia(int acertos) {
		DialogInterface.OnClickListener negativeEvent = new DialogInterface.OnClickListener() {

			public void onClick(DialogInterface dialog, int which) {
				dialog.dismiss();
				finish();
				
			}
		};
		
		DialogInterface.OnClickListener positiveEvent = new DialogInterface.OnClickListener() {

			public void onClick(DialogInterface dialog, int which) {
				clickCount = 0;
				executorSequencia = new ExecutorSequencia();
				executarSequencia();		
			}
		};

		String desejaContinuar = getString(R.string.deseja_jogar_novamente);
		String mensagem = recuperarMensagemInicial(acertos).concat(" " + desejaContinuar);
		DialogUtils.showDialogYesNo(R.string.attention, mensagem, this, positiveEvent,negativeEvent,R.drawable.sheep);
	}

	private String recuperarMensagemInicial(int acertos) {
		if(acertos > 6 && acertos < 10) {
			return getString(R.string.bom_resultado).concat(" " + acertos);
		} else if(acertos >= 10) {
			return getString(R.string.otimo_resultado).concat(" " + acertos);
		} else {
			return getString(R.string.que_pena_vc_errou).concat(" " + acertos);
		}
	}

	private void tratarAcerto() {
		clickCount ++;   
		if(!isPossibleTouch()) { // Acertou a sequencia  Toda
			exibirToastMessage(R.string.voce_acertou_iniciando_nova_sequencia);
			clickCount = 0;
			executarSequencia();
		}
	}
	
	private void exibirToastMessage(int resMessage) {
		Toast toast = Toast.makeText(MemoryGameActivity.this, resMessage, Toast.LENGTH_SHORT);
		//toast.setGravity(Gravity.CENTER, 0, 0);
		toast.show();
	}

	private boolean isPossibleTouch() {
		int size = sequenceIndexExpected.size() -1;
		if(canTouch && clickCount <= size) {
			return true;
		} else {
			return false;
		}
	}

	private void executarSequencia() {
		executorSequencia.adicionarNovoAnimalRandomicoSequencia();	
		executorSequencia.executar();	
		sequenceIndexExpected = executorSequencia.getSequenceIndex();
	}


	private class ExecutorSequencia extends EndAnimationListener {

		private List<Integer> listIndex = null;
		private List<Integer> sequenceIndex = new ArrayList<Integer>();
		private int iterator = 0;

		public ExecutorSequencia() {
			listIndex = getListIndex();
		}

		private List<Integer> getListIndex() {
			List<Integer> listIndex = new ArrayList<Integer>();
			for(AnimalButton animalButton : animais) {
				int index = animais.indexOf(animalButton);
				listIndex.add(index);
			}
			return listIndex;
		}

		public void onAnimationEnd(Animation animation) {
			iterator ++;
			if(iterator < sequenceIndex.size()) {
				int nextIndex = sequenceIndex.get(iterator);
				iniciarAnimacaoESom(nextIndex);	
			} else {
				canTouch = true;
				exibirToastMessage(R.string.sua_vez);
			}
		}

		public void executar() {
			canTouch = false;
			iterator = 0;
			int nextIndex = sequenceIndex.get(iterator);
			iniciarAnimacaoESom(nextIndex);
		}

		public void adicionarNovoAnimalRandomicoSequencia() {
			int nextValue = getRandomIndex();
			sequenceIndex.add(nextValue);
		}

		private void iniciarAnimacaoESom(int buttonIndex) {
			AnimalButton animalButton = animais.get(buttonIndex);
			Animation animation = AnimationController.createAnimationIncreaseSizeFaster(MemoryGameActivity.this);
			animation.setAnimationListener(this);
			animalButton.startAnimation(animation);	
			playSound(animalButton);
		}

		private int getRandomIndex() {
			Random random = new Random();
			int nextValue = random.nextInt(listIndex.size());
			return nextValue;
		}

		public List<Integer> getSequenceIndex() {
			return sequenceIndex;
		}

	}
}